import {
  IMetaHandleData,
  IMetaHandlePageData,
  IMetaListData,
  IMetaMultipleFormhandlePageData,
} from '@/views/common/types/operate';
import { useListTable } from '@/hooks/system/useListPage';
import { useMessage } from '@/hooks/web/useMessage';
import { computed, onMounted, ref } from 'vue';
import { useModal, useModalInner } from '@/components/Modal';
import { useDrawer, useDrawerInner } from '@/components/Drawer';
import { assign, forEach, isEmpty, isFunction, isNil, map } from 'lodash-es';
import { ActionItem } from '@/components/Table';
import { useCommonForm, usePopupForm } from '@/utils/module/formUtils';
import { usePermission } from '@/hooks/web/usePermission';
import { useRoute } from 'vue-router';
import { FormActionType } from '@/components/Form';

interface IApiService {
  useList: (meta: IMetaListData) => {};
  useHandle: (emit, meta: IMetaHandleData) => {};
  usePageHandle: (meta: IMetaHandlePageData) => {};
  useMultipleFormPageHandle: (meta: IMetaMultipleFormhandlePageData) => {};
}

const handleEditQuery = async (pkid, data, meta, formMethods) => {
  if (!isNil(meta.details) && isFunction(meta.details)) {
    let param: string | Recordable<string> = {};
    if (!isNil(meta.queryParams)) {
      meta.queryParams.forEach((item) => {
        if (!isNil(data[item])) {
          param[item] = data[item];
        }
      });
    } else {
      // @ts-ignore
      param = data[pkid].toString();
    }
    let res = await meta.details(param);

    if (isFunction(meta.queryResult)) {
      res = await meta.queryResult(res);
    }

    await formMethods.setFieldsValue(res);
    //查询结果后
    if (isFunction(meta.afterQuery)) {
      await meta.afterQuery(res);
    }
  }
};

class ApiV1 implements IApiService {
  public useList(meta: IMetaListData) {
    const { hasPermission } = usePermission();
    if (!isNil(meta.auth)) {
      if (!hasPermission(meta.auth)) {
        meta.tableProps.immediate = false;
      }
    }
    const [registerTable, tableMethods, selectMethods, excelMethods] = useListTable(
      meta.tableProps,
      meta.excelConfig,
    );

    const { createMessage } = useMessage();

    const showFooter = ref(true);

    const mode = meta.mode ?? 'model';
    let registerLayer: any;
    let openLayer: Fn;
    let userInnerMethod: any;
    if (mode == 'model') {
      const [registerModel, methods] = useModal();
      registerLayer = registerModel;
      userInnerMethod = methods;
      openLayer = methods.openModal;
    } else if (mode == 'drawer') {
      const [registerDrawer, methods] = useDrawer();
      registerLayer = registerDrawer;
      openLayer = methods.openDrawer;
      userInnerMethod = methods;
    }
    onMounted(() => {
      if (!isNil(meta.auth)) {
        if (!hasPermission(meta.auth)) {
          tableMethods.getForm().setProps({ showResetButton: false, showSubmitButton: false });
        }
      }
    });
    const methods = {
      //新增菜单
      handleCreate: () => {
        if (mode == 'model' || mode == 'drawer') {
          openLayer(true, { isUpdate: false });
        } else if (mode == 'page') {
          const addFn = meta.pageMethod?.addFn;
          if (!isNil(addFn) && isFunction(addFn)) {
            addFn();
          }
        }
      },
      //批量删除
      batchDelete: () => {
        const ids = selectMethods.selectedRowKeys.value;
        if (isEmpty(ids)) {
          createMessage.warning('请选择要删除的数据');
          return;
        }
        if (!isNil(meta.delFN) && isFunction(meta.delFN)) {
          meta.delFN(ids).then(() => {
            createMessage.success('删除成功');
            tableMethods.reload();
          });
        }
      },
      //操作菜单
      getTableAction: (record): ActionItem[] => {
        const pkid = meta.pkid ?? 'id';
        const pkidParam = {};
        pkidParam[pkid] = record[pkid];

        let actionItems: ActionItem[] = [];
        if (isFunction(meta.actionItems)) {
          actionItems = meta.actionItems(pkidParam, record);
        }

        const editItem: ActionItem = {
          label: '编辑',
          icon: 'ant-design:edit-outlined',
          // auth: 'system:senior:menu:edit',
          onClick: () => {
            if (mode == 'model' || mode == 'drawer') {
              showFooter.value = true;
              openLayer(true, assign({ isUpdate: true }, pkidParam));
            } else if (mode == 'page') {
              const editFn = meta.pageMethod?.editFn;
              if (!isNil(editFn) && isFunction(editFn)) {
                editFn(pkidParam, record);
              }
            }
          },
        };
        const delItem: ActionItem = {
          label: '删除',
          color: 'error',
          icon: 'ant-design:delete-outlined',
          popConfirm: {
            title: '是否确认删除',
            confirm: async () => {
              if (!isNil(meta.delFN)) {
                let param: string | Recordable<string> = {};
                if (!isNil(meta.queryParams?.delParam)) {
                  if (isFunction(meta.queryParams?.delParam)) {
                    param = await meta.queryParams.delParam(record);
                  } else {
                    meta.queryParams?.delParam.forEach((item) => {
                      if (!isNil(record[item])) {
                        param[item] = record[item];
                      }
                    });
                  }
                } else {
                  param = record[pkid];
                }
                meta.delFN(param).then(() => {
                  createMessage.success('删除成功');
                  tableMethods.reload();
                });
              }
            },
          },
        };

        if (!isNil(meta.editActionItem)) {
          if (isFunction(meta.editActionItem)) {
            actionItems.push(assign(editItem, meta.editActionItem(record)));
          } else {
            actionItems.push(assign(editItem, meta.editActionItem));
          }
        } else {
          actionItems.push(editItem);
        }

        if (!isNil(meta.delActionItem)) {
          if (isFunction(meta.delActionItem)) {
            actionItems.push(assign(delItem, meta.delActionItem(record)));
          } else {
            actionItems.push(assign(delItem, meta.delActionItem));
          }
        } else {
          actionItems.push(delItem);
        }

        return actionItems;
      },
    };
    return {
      registerTable,
      registerLayer,
      tableMethods,
      userInnerMethod,
      methods,
      showFooter,
      selectMethods,
      excelMethods,
    };
  }

  useHandle(emit, meta: IMetaHandleData) {
    // 当前是否是更新模式
    const isUpdate = ref<boolean>(false);
    const isDetail = ref<boolean>(false);
    const title = computed(() =>
      isNil(meta.customTitle) ? (isUpdate.value ? '编辑' : '新增') + meta.title : meta.customTitle,
    );
    const pkidValRef = ref('');
    const pkid = meta.pkid ?? 'id';
    const { createMessage } = useMessage();
    const showFooter = ref(true);
    //注册表单
    const [registerForm, formMethods] = usePopupForm(meta.formProps);
    const callback = async (data) => {
      await formMethods.resetFields();
      if (mode == 'drawer') {
        innerMethod.setDrawerProps({ showFooter });
      }

      //初始化
      if (isFunction(meta.beforeQuery)) {
        await meta.beforeQuery();
      }
      //
      innerMethod.changeOkLoading(false);
      isUpdate.value = !!data?.isUpdate;
      isDetail.value = data?.isDetail;
      innerMethod.changeOkLoading(false);

      if (isUpdate.value) {
        await handleEditQuery(pkid, data, meta, formMethods);
        pkidValRef.value = data[pkid];
      }
      if (isFunction(meta.commonQuery)) {
        await meta.commonQuery(isUpdate.value);
      }
      if (isDetail.value) {
        await formMethods.setProps({ disabled: true });
      }
    };
    const mode = meta.mode ?? 'model';
    let innerObj: any = [];
    if (mode == 'model') {
      innerObj = useModalInner(callback);
    } else if (mode == 'drawer') {
      innerObj = useDrawerInner(callback);
    }
    const [registerModel, innerMethod] = innerObj;
    const methods = {
      /**
       * 提交
       */
      handleSubmit: async () => {
        try {
          await formMethods.validate();
          let values = formMethods.getFieldsValue();
          forEach(values, (v, k) => {
            if (isNil(v)) {
              values[k] = '';
            }
          });
          if (isFunction(meta.beforeSubmit)) {
            values = await meta.beforeSubmit(values);
          }
          innerMethod.changeOkLoading(true);
          if (isNil(meta.debug) || meta.debug == false) {
            //提交表单
            if (isFunction(meta.saveOrUpdate)) {
              await meta.saveOrUpdate(values, isUpdate.value);
            }
            if (isUpdate.value) {
              if (isFunction(meta.updateFn)) {
                const mathes = /\((.*?)\)/gm.exec(Function.prototype.toString.call(meta.updateFn));

                if (mathes?.[1]) {
                  const args = mathes[1].split(',');
                  if (args.length > 1) {
                    await meta.updateFn(pkidValRef.value, values);
                  }
                } else {
                  await meta.updateFn(values);
                }
              }
            } else {
              if (isFunction(meta.saveFn)) {
                await meta.saveFn(values);
              }
            }
          } else {
            console.info('debug:', values);
          }

          if (mode == 'model') {
            innerMethod.closeModal();
          } else {
            innerMethod.closeDrawer();
          }
          emit('success', values);
        } catch (e) {
          if (Reflect.has(e as Object, 'type')) {
            createMessage.error(Reflect.get(e as Object, 'msg'));
          }
        } finally {
          innerMethod.changeOkLoading(false);
        }
      },
    };

    return { registerForm, registerModel, methods, formMethods, title };
  }

  usePageHandle(meta: IMetaHandlePageData) {
    const title = computed(() => {
      const { op } = route.query;
      if (!isNil(op)) {
        if (op == 'details') {
          return '详情' + meta.title;
        }
        return meta.title;
      } else {
        return isNil(meta.customTitle)
          ? (isUpdate.value ? '编辑' : '新增') + meta.title
          : meta.customTitle;
      }
    });
    const { createMessage } = useMessage();

    //注册表单
    const [registerForm, formMethods] = useCommonForm(meta.formProps);
    const isUpdate = ref(false);
    const route = useRoute();
    const loadingRef = ref(false);
    const pkid = meta.pkid ?? 'id';
    const pkidValRef = ref('');
    const detailsRef = ref(false);
    onMounted(async () => {
      const query = route.query;
      if (!isNil(query['op'])) {
        if (query['op'] == 'details') {
          detailsRef.value = true;
        }
      }

      //初始化
      if (isFunction(meta.beforeQuery)) {
        await meta.beforeQuery();
      }

      if (!isNil(query[pkid])) {
        await handleEditQuery(pkid, query, meta, formMethods);
        isUpdate.value = true;
        pkidValRef.value = <string>query[pkid];
      }

      if (isFunction(meta.commonQuery)) {
        await meta.commonQuery(isUpdate.value);
      }
      if (detailsRef.value) {
        await formMethods.setProps({ disabled: true });
      }
    });
    const methods = {
      /**
       * 提交
       */
      handleSubmit: async () => {
        try {
          await formMethods.validate();
          let values = formMethods.getFieldsValue();
          console.log(values);
          forEach(values, (k, v) => {
            if (isNil(k)) {
              values[v] = '';
            }
          });
          if (isFunction(meta.beforeSubmit)) {
            values = await meta.beforeSubmit(values);
          }
          loadingRef.value = true;
          await formMethods.setProps({
            submitButtonOptions: {
              loading: true,
            },
          });
          if (isNil(meta.debug) || meta.debug == false) {
            if (isFunction(meta.saveOrUpdate)) {
              //提交表单
              const res = await meta.saveOrUpdate(values, isUpdate.value);
              if (isNil(values[pkid])) {
                values[pkid] = res;
              }
            } else {
              if (isUpdate.value) {
                if (isFunction(meta.updateFn)) {
                  const mathes = /\((.*?)\)/gm.exec(
                    Function.prototype.toString.call(meta.updateFn),
                  );

                  if (mathes?.[1]) {
                    const args = mathes[1].split(',');
                    if (args.length > 1) {
                      await meta.updateFn(pkidValRef.value, values);
                    }
                  } else {
                    await meta.updateFn(values);
                  }
                }
              } else {
                if (isFunction(meta.saveFn)) {
                  const res = await meta.saveFn(values);
                  if (isNil(values[pkid])) {
                    values[pkid] = res;
                  }
                }
              }
            }
          } else {
            console.info('debug:', values);
          }

          createMessage.success('操作成功');
          if (isFunction(meta.finishJumpFn)) {
            await meta.finishJumpFn(values);
          }
        } catch (e) {
          if (Reflect.has(e as Object, 'type')) {
            createMessage.error(Reflect.get(e as Object, 'msg'));
          }
        } finally {
          loadingRef.value = false;
          await formMethods.setProps({
            submitButtonOptions: {
              loading: false,
            },
          });
        }
      },
      handleRestFn: async () => {
        await formMethods.resetFields();
      },
    };

    return { registerForm, methods, formMethods, title, loadingRef, detailsRef };
  }

  useMultipleFormPageHandle(meta: IMetaMultipleFormhandlePageData) {
    const title = computed(() => {
      const { op } = route.query;
      if (!isNil(op)) {
        if (op == 'details') {
          return '详情' + meta.title;
        }
        return meta.title;
      } else {
        return isNil(meta.customTitle)
          ? (isUpdate.value ? '编辑' : '新增') + meta.title
          : meta.customTitle;
      }
    });

    const isUpdate = ref(false);
    const route = useRoute();
    const loadingRef = ref(false);
    const pkid = meta.pkid ?? 'id';
    const pkidValRef = ref('');
    const detailsRef = ref(false);
    onMounted(async () => {
      const query = route.query;
      if (!isNil(query['op'])) {
        if (query['op'] == 'details') {
          detailsRef.value = true;
        }
      }

      //初始化
      if (isFunction(meta.beforeQuery)) {
        await meta.beforeQuery();
      }

      if (!isNil(query[pkid])) {
        if (!isNil(meta.details) && isFunction(meta.details)) {
          let param: string | Recordable<string> = {};
          if (!isNil(meta.queryParams)) {
            meta.queryParams.forEach((item) => {
              if (!isNil(query[item])) {
                param[item] = query[item];
              }
            });
          } else {
            // @ts-ignore
            param = query[pkid].toString();
          }
          let res = await meta.details(param);

          if (isFunction(meta.queryResult)) {
            res = await meta.queryResult(res);
          }
          // @ts-ignore
          pkidValRef.value = query[pkid].toString();
          for (const form of meta.forms) {
            if (!isNil(form)) {
              const { setFieldsValue, setProps } = form[1] as FormActionType;
              await setFieldsValue(res);
              if (detailsRef.value) {
                await setProps({ disabled: true });
              }
            }
          }

          //查询结果后
          if (isFunction(meta.afterQuery)) {
            await meta.afterQuery(res);
          }
        }
        isUpdate.value = true;
      }

      if (isFunction(meta.commonQuery)) {
        await meta.commonQuery(isUpdate.value);
      }
    });
    const { createMessage } = useMessage();
    const methods = {
      /**
       * 提交
       */
      handleSubmit: async () => {
        try {
          let values: Recordable = {};
          for (const form of meta.forms) {
            if (!isNil(form)) {
              const { validate, getFieldsValue } = form[1] as FormActionType;
              await validate();
              assign(values, getFieldsValue());
            }
          }
          forEach(values, (k, v) => {
            if (isNil(k)) {
              values[v] = '';
            }
          });
          if (isFunction(meta.beforeSubmit)) {
            values = await meta.beforeSubmit(values);
          }
          loadingRef.value = true;
          if (isNil(meta.debug) || meta.debug == false) {
            if (isFunction(meta.saveOrUpdate)) {
              //提交表单
              const res = await meta.saveOrUpdate(values, isUpdate.value);
              if (isNil(values[pkid])) {
                values[pkid] = res;
              }
            } else {
              if (isUpdate.value) {
                if (isFunction(meta.updateFn)) {
                  const mathes = /\((.*?)\)/gm.exec(
                    Function.prototype.toString.call(meta.updateFn),
                  );

                  if (mathes?.[1]) {
                    const args = mathes[1].split(',');
                    if (args.length > 1) {
                      await meta.updateFn(pkidValRef.value, values);
                    }
                  } else {
                    await meta.updateFn(values);
                  }
                }
              } else {
                if (isFunction(meta.saveFn)) {
                  const res = await meta.saveFn(values);
                  if (isNil(values[pkid])) {
                    values[pkid] = res;
                  }
                }
              }
            }
          } else {
            console.info('debug:', values);
          }

          createMessage.success('操作成功');
          if (isFunction(meta.finishJumpFn)) {
            await meta.finishJumpFn(values);
          }
        } catch (e) {
          if (Reflect.has(e as Object, 'type')) {
            createMessage.error(Reflect.get(e as Object, 'msg'));
          }
        } finally {
          loadingRef.value = false;
        }
      },
      handleRestFn: async () => {
        map(meta.forms, async (form) => {
          const { resetFields } = form[1] as FormActionType;
          await resetFields();
        });
      },
    };
    return { methods, title, loadingRef, detailsRef };
  }
}

export default new ApiV1();
